package controllers
//该文件不再使用
import (
	"findme-api/gpgga"
	"fmt"
	"github.com/astaxie/beego"
	"github.com/astaxie/beego/orm"
	"github.com/garyburd/redigo/redis"
	"github.com/gorilla/websocket"
	"net/http"
	"strconv"
	"strings"
	"time"
)

type MyWebSocketController struct {
	beego.Controller
}


//异常中断恢复函数
//func rec() {
//	if r := recover(); r != nil {
//		fmt.Println("Recovered", r)
//	}
//}


var UdpDataChan = make(chan []byte, 500)
//告警重发计数
var resendalarmtime = 0

//传入请求和应答，把结果返回给应答对象就可以了
var(
	wsConn *websocket.Conn
	err error
	//data []byte
	conn *Connection
)

//重发告警和取消告警函数信息
func ResendMessage(labelid string,confirmtype string,mjson Message){
	redisconn,err := redis.Dial("tcp","192.168.1.109:6379")
	if err != nil {
		fmt.Println("connect redis error :",err)
		return
	}
	//defer redisconn.Close()
	//for循环的逻辑是通过判断redis中的发送位来确认消息是否已被前端收到，如果没有收到，则不断重发
	//注意客户端收不到有两种情况，第一种是没发出去，第二种是发出去没收到

	for{
		isExist, err := redisconn.Do("hexists",labelid,confirmtype)
		fmt.Println("isExist",isExist)
		if err != nil {
			fmt.Println("err while checking keys:", err)
		}
		//标签id的key已经存在，则判断前端是否已经收到
		if isExist.(int64) == 1 {
			sendflag, err := redis.String(redisconn.Do("HGET",labelid,confirmtype))
			fmt.Println("sendflag:",sendflag)
			if err != nil {
				fmt.Println("redis get error:", err)
			}
			if sendflag == "Received"  {
				//前端已回应，则删除该标签id的key，并退出for循环
				FileLogs.Info("===================前端已回应，删掉key==============")
				//fmt.Println("===================前端已回应，删掉key==============")
				_, err = redisconn.Do("HDEL",labelid,confirmtype)
				if err != nil {
					fmt.Println("err while deleting:", err)
				}
				break
			}else {
				//前端没有回应，则不断重发直到收到回应
				FileLogs.Info("===================前端未回应，重发30次==============")
				//fmt.Println("===================前端未回应，重发30次==============")
				time.Sleep(5*time.Second)
				//if err = conn.WriteMessage([]byte(mString)); err != nil {
				//	fmt.Println(err)
				//	continue
				//	//return
				//}
				if resendalarmtime < 30 {
					//再次给前端发送告警
					message <- mjson
					resendalarmtime = resendalarmtime + 1
				}else {
					FileLogs.Info("=======已重发30次，删除key=======")
					//fmt.Println("=======已重发30次，删除key=======")
					_, err = redisconn.Do("HDEL", labelid,confirmtype)
					if err != nil {
						fmt.Println("err while deleting:", err)
					}
					resendalarmtime = 0
					break
				}
			}
		}else{
			FileLogs.Info("===================没有key，第一次发送==============")
			//fmt.Println("===================没有key，第一次发送==============")
			//给web端发告警
			//if err = conn.WriteMessage([]byte(mstring)); err != nil {
			//	fmt.Println(err)
			//	continue
			//	//return
			//}
			message <- mjson
			//设置标志位为已发送
			_, err = redisconn.Do("HSET", labelid, confirmtype,"Senddone")
			if err != nil {
				fmt.Println("redis set error:", err)
			}
			time.Sleep(3*time.Second)
		}
	}
}

/*
func (c *MyWebSocketController) GetWebsocket() {
	FileLogs.Info("===建立websocket链接==")

	upgrader := websocket.Upgrader{
		//这个回调函数的意思是握手的过程中遇到跨域问题，允许跨域
		CheckOrigin: func(r *http.Request) bool {
			return true;
		},
	}
	//传入 应答对象，请求对象，和顺带返回的Header,底层完成http 协议转换
	//在应答中返回 Upgrade:websocket 长连接 ,出错直接返回
	if wsConn,err = upgrader.Upgrade(c.Ctx.ResponseWriter, c.Ctx.Request,nil);err !=nil{
		return
	}

	if conn,err = InitConnection(wsConn);err !=nil{
		conn.Close()
	}

	//启动一个协程,每30秒给前端发消息，维持websocket链接
	go func(udpDatachan chan []byte) {

		for {
				////&&0000000，加速度传感器信息，定位类别，￥GPS，纬度，经度，海拔，净高，定位方式，定位状态码，包长，标签类别，设备ID，公司名
              UdpDataChan <- []byte("&&0000000,null,null,null,null,null,null,null,null,null,null,null,websocketheart,null")
			   time.Sleep(2*time.Second)
		}
		//ERR:
	   ////TODO:关闭链接的操作
		//  conn.Close()
	}(UdpDataChan)

	//遍历信道，读取数据
	for itemall := range UdpDataChan{
		//fmt.Println("==================读取信道=================: ", string(itemall))
		//log.Debug("itemall: ", string(itemall))

		capinfoarray := strings.Split(string(itemall), ",")

		//安全帽实时返回定位坐标
		if capinfoarray[0] == "&&0000000" {
			//fmt.Println("得到安全帽实时定位信息")
			//companyname := models.GetCompanyname(capinfoarray[13])
			//经度,纬度，海拔，净高，设备id
             //gpsinfo := capinfoarray[4]+"and"+capinfoarray[5]+"and"+capinfoarray[6]+"and"+capinfoarray[7]+"and" +capinfoarray[12]
			 m :=map[string]string{}
             m["longitude"] = capinfoarray[4]
             m["latitude"] = capinfoarray[5]
             m["height"] = capinfoarray[6]
             m["clearheight"] = capinfoarray[7]
             m["labelid"] = capinfoarray[12]
             m["company"] = capinfoarray[13]
             m["messagetype"] = "location"
			 mjson,_ :=json.Marshal(m)
			 mString :=string(mjson)

			if err = conn.WriteMessage([]byte(mString)); err != nil {
				return
			}
		} else if string(itemall[:5]) == "alarm" {
			FileLogs.Info("============收到告警==========")

			m :=map[string]string{}
			m["labelid"] = capinfoarray[1]
			m["company"] = capinfoarray[2]
			m["messagetype"] = "alarm"
			mjson,_ :=json.Marshal(m)
			mString :=string(mjson)
			//给web端发告警
			//if err = conn.WriteMessage([]byte(mString)); err != nil {
			//	fmt.Println(err)
			//	continue
			//	//return
			//}
			go ResendMessage(capinfoarray[1],"alarm",mString)

		} else if string(itemall[:5]) == "elecq"{
			//标签低电量告警
			if err = conn.WriteMessage([]byte(itemall)); err != nil {
				return
			}
		}else if string(itemall[:6]) == "cancel"{
			FileLogs.Info("===取消告警===")
			m :=map[string]string{}
			m["labelid"] = capinfoarray[1]
			m["company"] = capinfoarray[2]
			m["messagetype"] = "cancel"
			mjson,_ :=json.Marshal(m)
			mString :=string(mjson)

			//安全帽收到告警后取消告警
			//if err = conn.WriteMessage([]byte(mString)); err != nil {
			//	return
			//}

			go ResendMessage(capinfoarray[1],"cancel",mString)

		} else {
			//如果发生异常，处理中断并使程序继续执行
			//defer rec()
			ss :=Tool_DecimalByteSlice2HexString(itemall)
			datalength := HexDecc(ss[6:8]+ss[4:6])
			item := itemall[11:9+datalength]
			//fmt.Println("data item: ", string(item))
			FileLogs.Info("data item: ", string(item))
            //判断GPS字符串是否解析正确
			if string(item)[28:29] == "N"&& (string(item)[67:68]=="*"||string(item)[68:69]=="*"){
			//fmt.Println("ss: ",ss)
			labelid := HexDecc(ss[16:18]+ss[14:16]+ss[12:14]+ss[10:12])
			//解析出坐标字符串
			coordinate := gaggp.Gpgga(string(item))
			idstr := strconv.FormatInt(labelid,10)
            bb := coordinate + "and" + idstr
            //更新标签的位置坐标
			o := orm.NewOrm()
			_, err := o.Raw("update label_info set coordinate = ? where labelid = ?", coordinate,idstr).Exec()
			if err != nil{
				//fmt.Println("标签当前位置更新失败！")
				FileLogs.Info("标签当前位置更新失败！")
			}

			//使用websocket返回给前端
			if err = conn.WriteMessage([]byte(bb)); err != nil {
				return
			}
			}
		}
	}
}
*/

// 用于与用户间的websocket连接(chatRoom.html发送来的websocket请求)
func (c *MyWebSocketController) GetWebsocket() {
	companyname := c.GetString("companyname")
	fmt.Println("======新建websocket链接，公司名是=====:",companyname)
	if len(companyname) == 0 {
		beego.Error("name is NULL")
		c.Redirect("/", 302)
		return
	}

	//允许跨域
	upgrader := websocket.Upgrader{
		//这个回调函数的意思是握手的过程中遇到跨域问题，允许跨域
		CheckOrigin: func(r *http.Request) bool {
			return true;
		},
	}
	// 检验http头中upgrader属性，若为websocket，则将http协议升级为websocket协议
	conn, err := upgrader.Upgrade(c.Ctx.ResponseWriter, c.Ctx.Request, nil)
	//fmt.Println("err:",err)

	if _, ok := err.(websocket.HandshakeError); ok {
		beego.Error("Not a websocket connection")
		http.Error(c.Ctx.ResponseWriter, "Not a websocket handshake", 400)
		return
	} else if err != nil {
		beego.Error("Cannot setup WebSocket connection:", err)
		return
	}

	var client Client
	client.companyname = companyname
	client.conn = conn

	//如果用户列表中没有该用户
	if !clients[client] {
		join <- client
		FileLogs.Info("user:", client.companyname, "websocket connect success!")
	}

	// 当函数返回时，将该用户加入退出通道，并断开用户连接
	defer func() {
		leave <- client
		client.conn.Close()
	}()

	//启动一个协程,每30秒给前端发消息，维持websocket链接
	//go func(udpDatachan chan []byte) {
	//
	//	for {
	//		////&&0000000，加速度传感器信息，定位类别，￥GPS，纬度，经度，海拔，净高，定位方式，定位状态码，包长，标签类别，设备ID，公司名
	//		UdpDataChan <- []byte("&&0000000,null,null,null,null,null,null,null,null,null,null,null,websocketheart,所有公司")
	//		time.Sleep(10*time.Second)
	//	}
	//	//ERR:
	//	////TODO:关闭链接的操作
	//	//  conn.Close()
	//}(UdpDataChan)


	for itemall := range UdpDataChan {
		//fmt.Println("========未读缓冲区长度===========：", len(UdpDataChan))
		capinfoarray := strings.Split(string(itemall), ",")
		//fmt.Println("======capinfoarray======:", capinfoarray)
		//安全帽实时返回定位坐标
		if capinfoarray[0] == "&&0000000" {
			//fmt.Println("得到安全帽实时定位信息")
			//companyname := models.GetCompanyname(capinfoarray[13])
			//经度,纬度，海拔，净高，设备id
			//gpsinfo := capinfoarray[4]+"and"+capinfoarray[5]+"and"+capinfoarray[6]+"and"+capinfoarray[7]+"and" +capinfoarray[12]
			//m :=map[string]string{}
			//m["longitude"] = capinfoarray[4]
			//m["latitude"] = capinfoarray[5]
			//m["height"] = capinfoarray[6]
			//m["clearheight"] = capinfoarray[7]
			//m["labelid"] = capinfoarray[12]
			//m["company"] = capinfoarray[13]
			//m["messagetype"] = "location"
			//mjson,_ :=json.Marshal(m)
			//mString :=string(mjson)

			var msg Message
			msg.Longitude = capinfoarray[4]
			msg.Latitude = capinfoarray[5]
			msg.Height = capinfoarray[6]
			msg.Clearheight = capinfoarray[7]
			msg.Labelid = capinfoarray[12]
			msg.Companyname = capinfoarray[13]
			msg.Messagetype = "location"
			message <- msg
		} else if string(itemall[:5]) == "alarm" {
			FileLogs.Info("============收到告警==========")

			var msg Message
			msg.Labelid = capinfoarray[1]
			msg.Companyname = capinfoarray[2]
			msg.Messagetype = "alarm"
			//message <- msg

			go ResendMessage(capinfoarray[1], "alarm", msg)
		} else if string(itemall[:6]) == "cancel" {
			FileLogs.Info("===取消告警===")

			var msg Message
			msg.Labelid = capinfoarray[1]
			msg.Companyname = capinfoarray[2]
			msg.Messagetype = "cancel"
			//message <- msg

			go ResendMessage(capinfoarray[1], "cancel", msg)

		} else {
			fmt.Println("GPS人员定位")

			//如果发生异常，处理中断并使程序继续执行
			//defer rec()
			ss := Tool_DecimalByteSlice2HexString(itemall)
			datalength := HexDecc(ss[6:8] + ss[4:6])
			item := itemall[11 : 9+datalength]
			//fmt.Println("data item: ", string(item))
			FileLogs.Info("data item: ", string(item))
			if string(item)[28:29] == "N" && (string(item)[67:68] == "*" || string(item)[68:69] == "*") {
				//fmt.Println("ss: ",ss)
				labelid := HexDecc(ss[16:18] + ss[14:16] + ss[12:14] + ss[10:12])
				//解析出坐标字符串
				coordinate := gaggp.Gpgga(string(item))
				idstr := strconv.FormatInt(labelid, 10)
				bb := coordinate + "and" + idstr
				fmt.Println(bb)
				//更新标签的位置坐标
				o := orm.NewOrm()
				_, err := o.Raw("update label_info set coordinate = ? where labelid = ?", coordinate, idstr).Exec()
				if err != nil {
					//fmt.Println("标签当前位置更新失败！")
					FileLogs.Info("标签当前位置更新失败！")
				}

				//使用websocket返回给前端
				//if err = conn.WriteMessage([]byte(bb)); err != nil {
				//	return
				//}
			}
		}

	}
}




//从redis中接收告警和取消告警数据,定位数据
//channel1为告警频道，channel2为定位频道,
func Getdatafromredis(udpDatachan chan []byte) {
	conn, err := redis.Dial("tcp", "192.168.1.109:6379")
	//conn, err := redis.Dial("tcp", "47.105.190.126:6379")
	if err != nil {
		fmt.Println("connect redis error :", err)
		return
	}
	defer conn.Close()
	psc := redis.PubSubConn{conn}
	psc.Subscribe("channel1","channel2","channel3") //订阅channel1,channel2频道
	for {
		switch v := psc.Receive().(type) {
		case redis.Message:
			FileLogs.Info("message:", v.Channel, string(v.Data))
			//fmt.Println("message:", v.Channel,string(v.Data))
			udpDatachan <- []byte( v.Data)

			//FileLogs.SetLogger("===============缓冲区长度==============：",strconv.Itoa(cap(udpDatachan)))
			//FileLogs.Info("==============未读缓冲区长度===========：",strconv.Itoa(len(udpDatachan)))
			//信道缓冲区长度超过80还没有读取的话，就会减半释放
			if len(udpDatachan) > 80 {
				for j := 0; j < len(udpDatachan); j++ {
					<-udpDatachan
				}
			}
			//FileLogs.Info("===========释放后未读缓冲区长度========：",strconv.Itoa(len(udpDatachan)))
			//fmt.Println(strconv.Itoa(cap(udpDatachan)),strconv.Itoa(len(udpDatachan)),strconv.Itoa(len(udpDatachan)))
		case redis.Subscription:
			fmt.Printf("%s: %s %d\n", v.Channel, v.Kind, v.Count)
		case error:
			fmt.Println(v)
			return
		}
	}
}





//从标签接受定位数据包
/*
func Udpserver(udpDatachan chan []byte) {
	println("=============启动udp服务，从标签接收信息============")

	socket, err := net.ListenUDP("udp4", &net.UDPAddr{
		//IP:   net.IPv4(172, 31, 253, 53),
		IP:   net.IPv4(192, 168, 1, 206),
		//IP:   net.IPv4(172, 31, 253, 53),
		Port: 9000,
	})
	if err != nil {
		//fmt.Println("listern ", err)
		logs.Debug("listern err:", err)
		return
	}
	defer socket.Close()
	//1.更新标签信息
	//2.存储gps并给前端传送定位信息与告警信息
	//3.清空channel缓冲区
	//4.给标签发送告警

	for {
		data := make([]byte, 500)

		_, remoteAddr, err := socket.ReadFromUDP(data)
		//println("after")
		if err != nil {
			//fmt.Println("read data err:", err)
			logs.Debug("read data err:", err)
			continue
		}

		//fmt.Println("收到标签信息，地址是：", remoteAddr)
		logs.Debug("收到标签信息，地址是：", remoteAddr)
		//fmt.Println(reflect.TypeOf(remoteAddr.IP[0]))

		var un1 uint8 = remoteAddr.IP[0]
		//var ip1 int = int(un1)
		var un2 uint8 = remoteAddr.IP[1]
		//var ip2 int = int(un2)
		var un3 uint8 = remoteAddr.IP[2]
		//var ip3 int = int(un3)
		var un4 uint8 = remoteAddr.IP[3]
		//var ip4 int = int(un4)

		labelip := strconv.Itoa(int(un1))+"."+strconv.Itoa(int(un2))+"."+strconv.Itoa(int(un3))+"."+strconv.Itoa(int(un4))
		fmt.Println("labelip: ",labelip)


		//fmt.Println("get data from label ",data)
		//fmt.Println("get data from label",data)
		ss :=Tool_DecimalByteSlice2HexString(data)
		//fmt.Println("消息的十六进制字符串格式为：: ",ss)
		labelid := HexDecc(ss[16:18]+ss[14:16]+ss[12:14]+ss[10:12])
		datalength := HexDecc(ss[6:8]+ss[4:6])
		fmt.Println("labelid: ",labelid)
		fmt.Println("datalength: ",datalength)//数据段长度
		fmt.Println("datatype: ",string(data[10:11]))//数据类型

		//如果是安全帽数据，则单独处理，注意此处只接收了定位数据包，心跳包待定
		if ss[0:4] == "2626"{
			//&&0000000，加速度传感器信息，定位类别，￥GPS，纬度，经度，海拔，净高，定位方式，定位状态码，包长，标签类别，设备ID，校准位
			 fmt.Println("安全帽字符串：",string(data[:]))
			 capinfo := string(data[:]);
			 capinfoarray := strings.Split(capinfo, ",")

			timeUnix:=time.Now().Unix()
			timeStr:=time.Now().Format("2006-01-02 15:04:05")
			//添加ＧＰＳ数据
			gpsdata := models.GpsInfo{Data:capinfoarray[4]+","+capinfoarray[5],Labelid:capinfoarray[12],Timestamp:timeUnix,Datatimestr:timeStr}
			models.AddGps(&gpsdata)
			udpDatachan <- data[:]

			fmt.Println("===============安全帽缓冲区长度==============：",cap(udpDatachan))
			fmt.Println("==============安全帽未读缓冲区长度===========：",len(udpDatachan))
			//信道缓冲区长度超过80还没有读取的话，就会减半释放
			if len(udpDatachan) > 80 {
				for j := 0; j < len(udpDatachan); j++ {
					<-udpDatachan
				}
			}
			fmt.Println("===========安全帽释放后未读缓冲区长度========：",len(udpDatachan))
		}else {
			//如果是普通标签信息
			timeUnix := time.Now().Unix()
			timeStr := time.Now().Format("2006-01-02 15:04:05")
			//由于标签的IP和端口号会改变，所以需要先查询数据库的标签号
			var labelrows0 []models.LabelInfo
			o := orm.NewOrm()
			//if _, err := o.Raw("SELECT * FROM label_info WHERE labelid = ? and labelip = ? and labelport = ? ",labelid,labelip,strconv.Itoa(remoteAddr.Port)).QueryRows(&labelrows); err != nil{
			if _, err := o.Raw("SELECT * FROM label_info WHERE labelid = ?  ", labelid).QueryRows(&labelrows0); err != nil {
				fmt.Println("errr")
				//return
			}

			//fmt.Println(ss[10:18])
			flag := false
			//如果能查到，说明数据库里已经有标签存在
			for _, labelrow := range labelrows0 {
				fmt.Println("labelrows :", labelrow)
				fmt.Println("标签已经存在！")
				flag = true
				//fmt.Println(labelrow)
				break
			}
			fmt.Println("flag: ", flag)
			//fmt.Println("lenlabelid:",len(labelid))
			if labelid > 1000000 {
				continue
			}
			//没查到标签，则新增标签
			if (flag == false) {
				//添加标签
				labeldata := models.LabelInfo{
					Labelid: strconv.FormatInt(labelid, 10),
					Labelip: labelip, Labelport: strconv.Itoa(remoteAddr.Port),
					Labeltype:        "标签类型",
					Labeluser:        "标签使用者",
					Position:         "职务",
					Registered:       "未注册",
					Unit:             "所在名称",
					Department:       "所在部门",
					Coordinate:       "位置坐标",
					Changetime:       timeStr,
					Alarmflag:        "0",
					Electricquantity: "当前电量"}
				models.AddLabel(&labeldata)
			} else if (flag == true) {
				fmt.Println("更新标签：　", labelip)
				//查到标签，则修改标签ｉｐ和端口号
				_, err := o.Raw("update label_info set labelip = ?,labelport = ?,changetime = ? where labelid = ?", labelip, strconv.Itoa(remoteAddr.Port), timeStr, labelid).Exec()
				if err != nil {
					fmt.Println("更新失败！")
				}
			}

			//如果是标签心跳包，则更新电量信息，并检测是否发送低电量告警
			if ss[8:10] == "15" {
				//fmt.Println("====收到低电量信息====",ss)

				//给标签应答
				baghead := "2323"   //包头信息
				bagbody := "000015" //包长+类型
				//fmt.Println(baghead)
				hexlabelid := DecHex(labelid)
				if len(hexlabelid)%2 == 1 {
					hexlabelid = "0" + hexlabelid
				}
				len_hexlabelid := len(hexlabelid)

				//补齐8位用户id,改成小端模式
				for i := 0; i < 8-len_hexlabelid; i += 2 {
					hexlabelid = hexlabelid + "00"
				}
				fmt.Println("=====2labelid====:", hexlabelid)

				tmp1 := baghead + bagbody + hexlabelid

				//十六进制按位异或，忽略包头的两个字节
				tmp2 := Xor(tmp1)
				if len(tmp2) == 1 {
					tmp2 = "0" + tmp2
				}
				fmt.Println("tmp2: ", tmp2)
				tmp3 := tmp1 + tmp2
				fmt.Println("tmp3: ", tmp3)

				send_data, _ := hex.DecodeString(tmp3)
				fmt.Println("====send_data:====", send_data)
				fmt.Println(remoteAddr)

				socket.WriteToUDP(send_data, remoteAddr)

				ss := Tool_DecimalByteSlice2HexString(data[9:10])
				electricquantity := HexDecc(ss)

				if electricquantity != 0 {
					//更新电量信息
					_, err := o.Raw("update label_info set electricquantity = ? where labelid = ?", electricquantity, labelid).Exec()
					if err != nil {
						fmt.Println("更新失败！")
					}
				}

				if electricquantity < 30 {
					fmt.Println("发送低电量告警")
					udpDatachan <- []byte("elecqand" + strconv.FormatInt(labelid, 10) )
				}
			}
			//如果是标签ｇｐｓ定位信息，添加标签和ｇｐｓ信息到数据库，然后添加到通道
			if ss[8:10] == "10" && string(data[10:11]) == "G" {

				fmt.Println("====gpsstring====:", string(data[11:9+datalength]))

				//添加ＧＰＳ数据
				gpsdata := models.GpsInfo{Data: string(data[11 : 9+datalength]), Labelid: strconv.FormatInt(labelid, 10), Timestamp: timeUnix, Datatimestr: timeStr}
				models.AddGps(&gpsdata)

				udpDatachan <- data[:]
			}
			//如果是告警信息，则直接将告警标志和标签id添加到通道
			if ss[8:10] == "18" {
				fmt.Println("收到告警信息！")
				udpDatachan <- []byte("alarmand" + strconv.FormatInt(labelid, 10) )
			}

			fmt.Println("===============缓冲区长度==============：", cap(udpDatachan))
			fmt.Println("==============未读缓冲区长度===========：", len(udpDatachan))
			//信道缓冲区长度超过80还没有读取的话，就会减半释放
			if len(udpDatachan) > 80 {
				for j := 0; j < len(udpDatachan); j++ {
					<-udpDatachan
				}
			}
			fmt.Println("===========释放后未读缓冲区长度========：", len(udpDatachan))

			//查询是否有标签告警标志发生改变，如果有标签告警标志发生改变，则给该标签回应告警信息,并把告警标志改为0
			var labelrows []models.LabelInfo
			o1 := orm.NewOrm()
			if _, err := o1.Raw("SELECT * FROM label_info").QueryRows(&labelrows); err != nil {
				fmt.Println("err")
				return
			}
			for _, labelrow := range labelrows {
				if labelrow.Alarmflag == "1" {
					port, _ := strconv.Atoi(labelrow.Labelport)
					addr := &net.UDPAddr{IP: net.ParseIP(labelrow.Labelip), Port: port}

					fmt.Println("========addr=====:", addr)

					//给标签发送告警信息
					baghaed := "2323"   //包头信息
					bagbody := "030019" //包长+类型
					fmt.Println(baghaed)
					int64, _ := strconv.ParseInt(labelrow.Labelid, 10, 64)
					labelid := DecHex(int64)
					fmt.Println("=====1labelid====:", len(labelid))
					if len(labelid)%2 == 1 {
						labelid = "0" + labelid
					}
					len_labelid := len(labelid)
					//补齐8位用户id,改成小端模式
					for i := 0; i < 8-len_labelid; i += 2 {
						labelid = labelid + "00"
					}
					fmt.Println("=====2labelid====:", labelid)

					bagdata := Tool_DecimalByteSlice2HexString([]byte("A")) + "02" + "03"

					tmp1 := baghaed + bagbody + labelid + bagdata

					//十六进制按位异或，忽略包头的两个字节
					tmp2 := Xor(tmp1)
					if len(tmp2) == 1 {
						tmp2 = "0" + tmp2
					}

					fmt.Println("tmp2: ", tmp2)
					tmp3 := tmp1 + tmp2
					fmt.Println("tmp3: ", tmp3)
					send_data, _ := hex.DecodeString(tmp3)
					fmt.Println("send_data:", send_data)
					socket.WriteToUDP(send_data, addr)
					_, err := o.Raw("update label_info set alarmflag = '0' where labelid = ?", int64).Exec()
					if err != nil {
						fmt.Println("恢复告警标志位失败！")
						//return
					}
				}
			}
		}
	}
}
*/


